package util

import (
	"cdam/qiniu/qlang"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"math/rand"
	"reflect"
	"strconv"
	"strings"
	"time"
)


var  Seed  rand.Source

//给字符串生成md5
//@params str 需要加密的字符串
//@params salt interface{} 加密的盐
//@return str 返回md5码
func Md5Crypt(str string, salt ...interface{}) (CryptStr string) {
	if l := len(salt); l > 0 {
		slice := make([]string, l+1)
		str = fmt.Sprintf(str+strings.Join(slice, "%v"), salt...)
	}
	return fmt.Sprintf("%x", md5.Sum([]byte(str)))
}

var letters = []byte("abcdefghjkmnpqrstuvwxyz123456789")
var longLetters = []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=_")

func init() {
	rand.Seed(time.Now().Unix())
}

// RandLow 随机字符串，包含 1~9 和 a~z - [i,l,o]
func RandLow(n int) []byte {
	if n <= 0 {
		return []byte{}
	}
	b := make([]byte, n)
	arc := uint8(0)
	if _, err := rand.Read(b[:]); err != nil {
		return []byte{}
	}
	for i, x := range b {
		arc = x & 31
		b[i] = letters[arc]
	}
	return b
}

// RandUp 随机字符串，包含 英文字母和数字附加=_两个符号
func RandUp(n int) []byte {
	if n <= 0 {
		return []byte{}
	}
	b := make([]byte, n)
	arc := uint8(0)
	if _, err := rand.Read(b[:]); err != nil {
		return []byte{}
	}
	for i, x := range b {
		arc = x & 63
		b[i] = longLetters[arc]
	}
	return b
}

// RandHex 生成16进制格式的随机字符串
func RandHex(n int) []byte {
	if n <= 0 {
		return []byte{}
	}
	var need int
	if n&1 == 0 { // even
		need = n
	} else { // odd
		need = n + 1
	}
	size := need / 2
	dst := make([]byte, need)
	src := dst[size:]
	if _, err := rand.Read(src[:]); err != nil {
		return []byte{}
	}
	hex.Encode(dst, src)
	return dst[:n]
}

func Interface2String(inter interface{}) string {

	switch inter.(type) {

	case string:
		return inter.(string)
		break
	case int:
		return strconv.FormatInt(int64(inter.(int)),10)
		break
	case float64:
		return strconv.FormatFloat(inter.(float64),'f',-1,64)
		break
	}
	return ""

}

func ConverInterfaceToString(param interface{}) string {
	result := ""
	if param != nil {
		if strings.Contains(reflect.TypeOf(param).String(),"map"){
			res,_ := json.Marshal(param)
			return string(res)
		}else{
			return param.(string)
		}

	}
	return result
}

func ConvertStringToMap(param string) (map[string]interface{},error)  {
	var maps map[string]interface{}
	if err := json.Unmarshal([]byte(param),&maps); err == nil {
		return maps,nil
	}else{
		return nil,err
	}
}

func CovertInterfaceToJSonString(param interface{})(result string) {
	result = ""
	if param != nil {
		r, err := json.Marshal(param)
		if err == nil {
			result = string(r)
		}
	}
	return result
}

func ExecuteQingQiuScript(expression string, params map[string]interface{}, name string) (map[string]interface{},error) {
	ql := qlang.New()
	for key,value := range params {
		ql.SetVar(key,value)
	}
	err := ql.Exec([]byte(expression),name)
	if err == nil {
		return ql.Context.CopyVars(),nil
	}else{
		return nil,err
	}
}